#include "app_porting.h"

/*
input:
	poutbuf (out) - wraped protocol packet
	outbuf_len (in) - size of  poutbuf 
	cmd (in) - protocol command
	pdata (in) 
	data_len - size of pdata buf
	
return:
	FAIL - -1
	SUCCUSS - actlly data length
*/
/*header(1B)+cmd(1B)+len(2B)+data(nB)+acc(1B)*/
int32_t inner_wrapper(uint8_t *poutbuf, int32_t outbuf_len, uint8_t cmd, uint8_t *pdata, int32_t data_len)
{
	int32_t len;
	int32_t i;
	uint8_t acc;
	
	if(NULL==poutbuf
		||data_len+INNER_PAD_LEN>outbuf_len){
		return LS_FAIL;
	}

	len=0;
	poutbuf[len++]=INNER_PROT_HEADER;
	poutbuf[len++]=cmd;
	len+=2;	
	for(i=0;i<data_len;i++){
		poutbuf[len++]=pdata[i];
	}	
	poutbuf[2]=(uint8_t)(len+1);
	poutbuf[3]=(uint8_t)((len+1)>>8);

	acc=0;
	for(i=0;i<len;i++){
		acc+=poutbuf[i];
	}
	poutbuf[len++]=acc;
	return len;
}

/*header(1B)+cmd(1B)+len(2B)+data(nB)+acc(1B)*/
int32_t inner_extractor(uint8_t *pinbuf, int32_t inbuf_len, uint8_t *pcmd, uint8_t *pdata, int32_t *pdata_len)
{
	int32_t len=0;
	int32_t i;
	uint16_t pkg_len;
	int32_t dat_len;
	uint8_t acc_orig,acc;

	if(NULL==pinbuf
		||NULL==pcmd
		||NULL==pdata
		||NULL==pdata_len) {
		return LS_FAIL;
	}
	
	if(inbuf_len<INNER_PAD_LEN){
		return LS_FAIL;
	}	

	if(INNER_PROT_HEADER!=pinbuf[len++]){
		return LS_FAIL;
	}

	*pcmd=pinbuf[len++];
	pkg_len=pinbuf[len++];
	pkg_len|=pinbuf[len++]<<8;
	if(inbuf_len!=pkg_len){
		return LS_FAIL;
	}
	
	dat_len=pkg_len-INNER_PAD_LEN;
	*pdata_len=dat_len;
	
	for(i=0;i<dat_len;i++){
		pdata[i]=pinbuf[len++];
	}
	acc_orig=pinbuf[len++];

	acc=0;
	for(i=0;i<pkg_len-1;i++){
		acc+=pinbuf[i];
	}

	if(acc==acc_orig){
		return LS_SUCCESS;
	}else{
		return LS_FAIL;
	}
}


int32_t inner_packet_receive(UART_DEVICE_E dev, unsigned char *pbuf, unsigned int receive_len, unsigned int wait_ms)
{
#define INNER_PACKET_REMINDER_WAIT_MS 10	

	int32_t len;
	
	while(1){
		len=uart_get_buf(dev,pbuf,1,wait_ms);
		if(0==len){
			return 0;
		}
		if(INNER_PROT_HEADER==pbuf[0]){
			break;
		}
	}
	pbuf+=len;
	len=uart_get_buf(dev,pbuf,3,wait_ms);
	if(3!=len){
		return 0;
	}

	len=pbuf[1]+(int32_t)(pbuf[2]<<8);
	len-=4;
	if(len>receive_len){		
		return 0;
	}

	receive_len=len;
	pbuf+=3;
	len=uart_get_buf(dev,pbuf,receive_len,wait_ms);
	if(len!=receive_len){
		return 0;
	}

	return (len+4);
}



